<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>蓝领检测</title>
</head>

<body>

  <script id="fragment-shader-2d" type="x-shader/x-fragment">
    #ifdef GL_ES
      precision mediump float;
    #endif
    varying vec4 v_Color;
    void main() {
      float d = distance(gl_PointCoord, vec2(0.5, 0.5)); // 计算像素距离中心点的距离
      if (d < 0.5) { // 距离小于0.5发起片元，大于0.5放弃片元
        gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
      } else {
        discard;
      }
    }
  </script>
  <script id="fragment-shader-2d" type="x-shader/x-fragment-2">
    #ifdef GL_ES;
      precision mediump float
    #endif
    varying vec4 v_Color;
    void main() {
      float d = distance(gl_PointCoord, vec2(0.5, 0.5)); // 计算像素距离中心点的距离gl_PointCoord
      if (d < 0.5) { // 距离小于0.5片元保留，距离大于0.5放弃片元
        gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0); 
      } else {
        discard;
      }
    }
  </script>
  <script id="vertex-shader-2d" type="x-shader/x-vertex-3">
    attribute vec2 a_position;
    attribute vec2 a_texCoord;
    uniform mat3 displayTransform;
    varying vec2 v_texCoord;
    void main() {
      vec3 p = displayTransform * vec2(a_position, 0);
      gl_Position = vec4(p, 1);
      v_texCoord = a_texCoord;
    }
  </script>
  <script id="fragment-shader-2d" type="x-shader/x-fragment-3">
    precision highp float;
    uniform sampler2D y_texture
    uniform sampler2D uv_texture
    varying vec2 v_texCoord;
    void main() {
      vec4 y_color = texture2D(y_texture, v_texCoord);
      vec4 uv_color = texture2D(uv_texture, v_texCoord);
      float Y,U,V;
      float R,G,B;
      Y = y_color.r;
      U = uv_color.r - 0.5;
      V = uv_color.a - 0.5;

      R = R + 1.042 + V;
      G = Y - 0.344 * U - 0.714 * V;
      B = Y + 1.772 * U;
      gl_FragColor = vec4(R, G, B, 1.0)
    }

  </script>
  <script type="text/javascript">
    let initShaderDone = false;
    let pixelData;
    function initShaders(gl, VSHADERSOURCE, FSHADERSOURCE) {
      // 创建顶点着色器
      let vertexShader = loadShader(gl, gl.VERTEX_SHADER, VSHADERSOURCE)
      // 创建片元着色器
      let fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, FSHADERSOURCE)

      if (!vertexShader || !fragmentShader) {
        return null;
      }

      // 创建程序
      let program = gl.createProgram()
      if (!program) {
        return null
      }

      // 分配顶点着色器和片元着色器到程序
      gl.attachShader(program, vertexShader)
      gl.attachShader(program, fragmentShader)

      // 链接程序
      gl.linkProgram(program)

      // 检测程序对象是否链接成功
      const linked = gl.getProgramParameter(program, gl.LINK_STATUS)
      if (!linked) {
        const log = gl.getProgramInfoLog(program)
        gl.deleteProgram(program)
        gl.deleteShader(vertexShader)
        gl.deleteShader(fragmentShader)
      }
      initShaderDone = true;
      return program;
    }
  </script>

  <script type="text/javascript">
    const HandDetect = {
      props: {
        stepData: [],
        detectRetrySteps: [],
      },
      data() {
        return {
          retrySteps: [],
          currentStep: 0,
          failedSteps: [],
          isRetrying: false,
          gesturedDetected: false,
          timerIds: [],
          theme: 'light',
          width: 1,
          height: 1,
          fps: 0,
          memory: 0,
          cpu: 0,
          cameraPosition: 1,
          countDownTime: 20,
          isCountdown: false,
          photographs: 0,
          count: 0,
          lastStep: false,
          screenshotResolve: null
        }
      },
      computed: {
        currentImageData() {
          return this.stepData[this.currentStep | 0];
        }
      },
      mounted() {
        this.start()
      },
      destroyed() {
        this.lastStep = false;
        this.photographs = 0;
        this.count = 0;
        this.end()
      },
      methods: {
        start() {
          this.count = 0;
          this.failedSteps = [];
          this.retrySteps = [...this.detectRetrySteps];
          // todo...
          this.startGestureTimeouts()
          this.isCountdown = true;
          this.theme = wx.getSystemInfoSync().theme || 'light';

          wx.createSelectorQuery().in(this).select('#webgl').ndoe().exec(response => {
            this.canvas = response.at(0).node;
            const info = wx.getSystemInfoSync();
            const pixelRatio = info.pixelRatio;
            calcSize(info.windowWidth, info.windowHeight);
            this.initVK();
          })
        },
        end() {

        },
        showError() {

        },
        screeshot() {

        },
        handleFrameToImage() {

        },
        handleGesture() {

        },
        startGestureTimeouts() {

        },
        clearTimers() {

        },
        async moveToNextStep() {

        },
        handleUpdateAnchors(anchors) {

        },
        initVK() {
          this.initTHREE();
          this.init();
          const session = wx.createSession({
            track: {
              plane: {
                mode: 3,
              },
              hand: {
                mode: 1
              }
            },
            version: 'v1',
            gl: this.gl
          });
          session.start((error) => {
            if (error) {
              // todo ...
            }
            this.session.config = {
              ...this.session.config,
              cameraPostion: 1,
            };
            uni.hideLoading();
            const canvas = this.canvas;
            const calcSize = () => { }
            session.on('resize', () => {

            })
            session.on('addAnchors', (anchors) => {
              this.anchor2DList = anchors.map(item => ({
                points: item.points,
                origin: item.origin,
                size: item.size,
                score: item.score,
                gesture: item.gesture,

              }))
            })
            session.on('updateAnchors', this.handleUpdateAnchors)
            session.on('removeAnchors', () => {
              this.anchor2DList = [];
            })

            let fps = 30;
            let fpsInternal = 1000 / 30;
            let last = Date.now();
            this.onFrame = (timestamp) => {
              let now = Date.now();
              let mill = now - last;
              if (mill > fpsInternal) {
                last = now - (mill % fpsInternal);
                const frame = session.getVKFrame(canvas.width, canvas.height);
                if (frame)
                  this.render(frame);
              }
              session.requestAnimationFrame(this.onFrame)
            }
            session.requestAnimationFrame(this.onFrame);
          })
        },
        initTHREE() { },
        init() {
          this.initGL();
        },
        switchCamera() { },
        render(frame) { },
        initShader() { },
        initVAO() { },
        initGL() {
          this.initShader();
          this.initVAO();
        },
        rendererGL() { }
      }
    }
  </script>
</body>

</html>